// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// E [author] rhyme_lph
// S [email]  rhymelph@gmail.com
// b [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/employee_contact_entity.dart';
import 'package:finance_app/src/entities/invite_member_entity.dart';
import 'package:finance_app/src/entities/invite_member_model.dart';
import 'package:finance_app/src/entities/role_permission_entity.dart';
import 'package:finance_app/src/http_service/http_invitation_service.dart';
import 'package:finance_app/src/http_service/http_permission_service.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/widgets/bottom_sheet/delete_info_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/list_select_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:fluttercontactpicker/fluttercontactpicker.dart';

class InviteTeamMembersProvider extends BaseProvider<List<InviteMemberEntity>> {
  String currentSelectEnable = 'Active';

  List<InviteMemberModel> modelList = [];

  List<String> menuList = ['Manage Role Access', 'Assign Role By Batch'];

  List<RolePermissionEntity> roles = [];

  @override
  Future get dataFuture => HttpInvitationService.invitationMembers(currentSelectEnable?.toLowerCase() == 'active' ? 'all' : currentSelectEnable?.toLowerCase());

  void onSelectPersonType(String value) {}

  void onSelectMenu(String value) {
    switch (value) {
      case 'Manage Role Access':
        onNavManageRolePage();
        break;
      case 'Assign Role By Batch':
        onAssignRoleByBatch();
        break;
    }
  }

  @override
  void initState() {
    super.initState();
    loadRoles();
  }

  @override
  void dispose() {
    super.dispose();
    modelList.forEach((element) {
      element.dispose();
    });
  }

  void onRaidoChoice(int index, int value) {
    modelList[index].radioSelect = value;
    update();
  }

  void onAssignRoleByBatch() async {
    final result = await Routes.navigateTo(RouterGenProviders.assignRoleByBatchPage, params: {});
    if (result != null) {
      await post(HttpInvitationService.invitationMembers(currentSelectEnable?.toLowerCase() == 'active' ? 'all' : currentSelectEnable?.toLowerCase()),
          onSuccess: (result) {
        data = getEntityFromResult<List<InviteMemberEntity>>(result);
        roles.add(RolePermissionEntity()..name = 'Disable');
      });
      update();
    }
  }

  void onAddFromEmployee() async {
    bool canInvite = canSendInvitation();
    if (!canInvite) return;
    final result = await Routes.navigateTo(RouterGenProviders.employeeBatchSelectPage, params: {'isSelectMode': true});
    if (result != null) {
      List<EmployeeContactEntity> employeeList = result;
      modelList.addAll(employeeList.map((e) {
        final item = InviteMemberModel();
        item.employeeId = e.id;
        item.phoneController.text = e.phoneNumber;
        item.countryCode = e.countryCode;
        item.emailController.text = e.email;
        item.nameController.text = e.name;
        item.countryCode = '+65';
        item.role = roles[1];
        item.radioSelect = e.phoneNumber.isNotEmpty && e.email.isEmpty ? 1 : 0;
        return item;
      }).toList());
      update();
    }
  }

  void onNavManageRolePage() async {
    await Routes.navigateTo(
      RouterGenProviders.manageRoleAccessPage,
    );
    loadRoles();
  }

  void onAddManually() {
    bool canInvite = canSendInvitation();
    if (!canInvite) return;
    final item = InviteMemberModel();
    item.countryCode = '+65';
    if (roles.isNotEmpty && roles.length != 0) item.role = roles[1];
    modelList.add(item);
    update();
  }

  void onImportFromPhoneBook() async {
    bool canInvite = canSendInvitation();
    if (!canInvite) return;
    bool isSuccess;
    if (!(await FlutterContactPicker.hasPermission())) {
      isSuccess = await FlutterContactPicker.requestPermission();
    } else {
      isSuccess = true;
    }
    if (isSuccess) {
      PhoneContact phoneContact = await FlutterContactPicker.pickPhoneContact();
      if (phoneContact != null) {
        final phoneNumber = phoneContact.phoneNumber;
        final name = phoneContact.fullName;
        final item = InviteMemberModel();
        item.phoneController.text = phoneNumber.number;
        item.countryCode = '+65';
        item.nameController.text = name;
        item.radioSelect = 1;
        item.role = roles[1];
        modelList.add(item);
        update();
      }
    }
  }

  void onRemoveTeamMembers(int index) {
    obtainContext?.call((context) async {
      bool isSuccess = await showRemoveInvitationBottomSheet(context);
      if (isSuccess == true) {
        final item = data[index];
        isSuccess = false;
        await post(HttpInvitationService.invitationRemove(item.id), autoHandler: AutoHandler.Toast, loadingTip: S.current.loading, onSuccess: (result) {
          isSuccess = true;
        });
        if (isSuccess) {
          await showInvitationRemovedSuccessBottomSheet(context);
          data.removeAt(index);
          update();
        }
      }
    });
  }

  void onRemoveInviteMembers(int index) {
    final model = modelList.removeAt(index);
    Future.delayed(Duration(milliseconds: 800), () {
      model.dispose();
    });
    update();
  }

  void onUpdateCountryCode(String data, int index) {
    modelList[index].countryCode = data;
    update();
  }

  void onUpdateType(RolePermissionEntity role, int index) {
    modelList[index].role = role;
    update();
  }

  void onInvite() async {
    FocusManager.instance.primaryFocus.unfocus();
    if (modelList.length == 0) return;
    List members = [];
    members.addAll(modelList
        .where((element) => element.radioSelect == 0
            ? element.emailController.text.isNotEmpty && element.emailController.text.isNotEmpty
            : element.phoneController.text.isNotEmpty && element.nameController.text.isNotEmpty)
        .map((e) => {
              'employee_id': e.employeeId,
              'name': e.nameController.text,
              'role_id': e.role.id,
              'country_code': e.radioSelect == 0 ? "0" : e.countryCode,
              'invite_account': e.radioSelect == 0 ? e.emailController.text : e.phoneController.text,
            })
        .toList());
    bool isSuccess = false;
    await post(HttpInvitationService.invite(members), loadingTip: S.current.loading, autoHandler: AutoHandler.Toast, onSuccess: (result) {
      isSuccess = true;
    });

    if (isSuccess) {
      modelList.forEach((element) {
        Future.delayed(Duration(milliseconds: 800), () {
          element.dispose();
        });
      });
      modelList.clear();
      update();
      obtainContext?.call((context) async {
        await showInvitationSendSmsSuccessBottomSheet(context);
        onRefreshData();
      });
    }
  }

  void onRefreshData() async {
    await post(dataFuture, loadingTip: S.current.loading, autoHandler: AutoHandler.Toast, onSuccess: (result) {
      data = getEntityFromResult<List<InviteMemberEntity>>(result);
      transformData(data, false);
      update();
    });
  }

  void onChangeSelectEnable() {
    obtainContext?.call((context) async {
      final result = await showStatusSelectBottomSheet(context, currentSelectEnable);
      if (result != null && currentSelectEnable != result) {
        currentSelectEnable = result;
        onRefreshData();
      }
    });
  }

  void onSelectInvitationMember(RolePermissionEntity role, int index) async {
    // if (role.name == 'Add New') {
    //   final result = await Routes.navigateTo(RouterGenProviders.newRolePage,
    //       params: {'isGoBack': true});
    //   print(result);
    //   if (result == null) return;
    //   role = result;
    // }

    if (role.name == 'Disable') {
      obtainContext?.call((context) async {
        bool isSuccess = await showDisableInvitationBottomSheet(context);
        if (isSuccess == true) {
          isSuccess = false;
          await post(HttpInvitationService.invitationDisable(data[index].id), autoHandler: AutoHandler.Toast, loadingTip: S.current.loading,
              onSuccess: (result) {
            isSuccess = true;
          });
          if (!isSuccess) {
            update();
          } else {
            data[index].enabled = 0;
            showInvitationDisableSuccessBottomSheet(context);
            data.removeAt(index);
            update();
          }
        } else {
          update();
        }
      });
    } else {
      bool isSuccess = false;
      await post(
          HttpPermissionService.setUserRoles(
            role.id,
            role.name,
            users: [
              {'id': data[index].id}
            ],
          ),
          autoHandler: AutoHandler.Toast,
          loadingTip: S.current.loading, onSuccess: (result) {
        isSuccess = true;
      });
      if (!isSuccess) {
        update();
      } else {
        data[index].role = role;
        onRefreshData();
        await post(HttpPermissionService.getMyPermission(), onSuccess: (result) async {
          RolePermissionEntity myRole = getEntityFromResult<RolePermissionEntity>(result);
          RProvider.myProvider.globalMap[ConfigKey.rolePermission] = myRole;
          await RProvider.myProvider.updateGlobalMap();
        });
      }
    }
  }

  void loadRoles() async {
    await post(HttpPermissionService.getAllRoles(), onSuccess: (result) {
      roles = getEntityFromResult<List<RolePermissionEntity>>(result);
      roles.add(RolePermissionEntity()..name = 'Disable');
      // roles.add(RolePermissionEntity()..name = 'Add New');
    });
    update();
  }

  bool canSendInvitation() {
    FocusManager.instance.primaryFocus.unfocus();
    if (Config.currentSubscription?.plan == null ||
        (Config.currentSubscription?.plan?.name == 'starting' && data.length + modelList.length >= 2) ||
        (Config.currentSubscription?.plan?.name == 'growing' && data.length + modelList.length >= 7)) {
      obtainContext?.call((context) {
        showReadyForUpgradeBottomSheet(context);
      });
      return false;
    } else {
      return true;
    }
  }

  @override
  FutureOr<List<InviteMemberEntity>> transformData(List<InviteMemberEntity> d, bool isCache) async {
    if (currentSelectEnable == 'Active') {
      data.removeWhere((element) => element.enabled == 0);
    }
    return super.transformData(data, isCache);
  }
}
